package com.fowo.api.service.handleWork;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.entity.*;
import com.fowo.api.model.listing.father.ListingFatherVo;
import com.fowo.api.model.loan.monthly.balance.LoanMonthlyBalanceVo;
import com.fowo.api.model.loan.now.balance.LoanNowBalanceVo;
import com.fowo.api.model.purchase.change.order.PurchaseChangeOrderBulkAuditingAction;
import com.fowo.api.model.purchase.change.order.PurchaseChangeOrderVo;
import com.fowo.api.model.purchase.change.order.product.PurchaseChangeOrderProductItemVo;
import com.fowo.api.model.purchase.order.PurchaseOrderVo;
import com.fowo.api.model.purchase.order.product.PurchaseOrderProductItemVo;
import com.fowo.api.service.ListingFatherService;
import com.fowo.api.service.PurchaseChangeOrderService;
import com.fowo.api.service.impl.*;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class PurchaseChangeOrderBulkAuditing implements PurchaseChangeOrderBulkAuditingAction {

    @Resource
    private PurchaseChangeOrderService purchaseChangeOrderService;
    @Resource
    private PurchaseOrderServiceImpl purchaseOrderService;
    @Resource
    protected PurchaseOrderProductServiceImpl purchaseOrderProductService;
    @Resource
    protected PurchaseChangeOrderProductServiceImpl purchaseChangeOrderProductService;
    @Resource
    private StockInServiceImpl stockInService;
    @Resource
    protected StockInProductServiceImpl stockInProductService;
    @Resource
    private LoanNowBalanceServiceImpl loanNowBalanceService;
    @Resource
    private LoanMonthlyBalanceServiceImpl loanMonthlyBalanceService;
    @Resource
    private ListingFatherService listingFatherService;


    @Transactional
    @Override
    public void run(List<Long> idList) throws Exception {
        for(Long id : idList){
            handle(id);
        }
    }

    private synchronized void handle(Long id) throws Exception {
        PurchaseChangeOrderVo voById = purchaseChangeOrderService.getVoById(id);
        Assert.isTrue(voById.getStatus().equals("0"),"该订单已处理完成");
        PurchaseOrder purchaseOrder = purchaseOrderService.getOne(Wrappers.<PurchaseOrder>query().lambda().eq(PurchaseOrder::getPurchaseOrderCode, voById.getOrderSn()));

        List<PurchaseChangeOrderProduct> list = purchaseChangeOrderProductService.list(Wrappers.<PurchaseChangeOrderProduct>query().lambda()
                .eq(PurchaseChangeOrderProduct::getParentPurchaseChangeOrder, voById.getId()));
        //获取采购单号所有的入库单
        List<StockIn> stockInList = stockInService.list(Wrappers.<StockIn>query().lambda().eq(StockIn::getPurchaseOrderCode, purchaseOrder.getPurchaseOrderCode()));
        if(purchaseOrder.getAnStatus().equals("9")){
            purchaseOrder.setAnStatus("2");
        }
        //设置成待到货状态
        purchaseOrder.setArrivalStatus("1");
        //修改采购订单
        updatePurchaseOrder(voById, purchaseOrder, list);
        //修改入库的价格
        updateStockIn(stockInList,list);
        //修改请款池金额
        updateFundsPayPool(voById);
        //更新状态
        voById.setStatus("1");
        purchaseChangeOrderService.update(voById);
        //判断是否都完成了
        isCompleted(purchaseOrder);
    }

    private void isCompleted(PurchaseOrder purchaseOrder) {
        PurchaseOrder purchaseOrder2 = purchaseOrderService.getById(purchaseOrder.getId());
        List<PurchaseOrderProduct> list = purchaseOrderProductService.list(Wrappers.<PurchaseOrderProduct>query().lambda().eq(PurchaseOrderProduct::getPurchaseOrderId, purchaseOrder2.getId()));
        long count = list.stream().filter(x -> x.getQuantityReceived() != null && x.getQuantityReceived().intValue() == x.getApplicationNum().intValue()).count();
        if(count==list.size()){
            purchaseOrder2.setArrivalStatus("2");
            purchaseOrder2.setAnStatus("9");
            purchaseOrderService.updateById(purchaseOrder2);
        }
    }

    /**
     * 修改入库价格
     * @param stockInList 入库单
     * @param purchaseChangeOrderProducts 变更单子表
     */
    private void updateStockIn(List<StockIn> stockInList,List<PurchaseChangeOrderProduct> purchaseChangeOrderProducts) {
        if(stockInList.size()>0){
            List<Long> collect = stockInList.stream().map(StockIn::getId).collect(Collectors.toList());
            List<StockInProduct> list = stockInProductService.list(Wrappers.<StockInProduct>query().lambda().in(StockInProduct::getParentStockInId, collect));
            for(StockInProduct stockInProduct : list){
                final PurchaseChangeOrderProduct purchaseChangeOrderProduct = purchaseChangeOrderProducts.stream().filter(c ->
                        c.getProductId().equals(stockInProduct.getProductId())).findFirst().get();
                stockInProduct.setCostPrice(purchaseChangeOrderProduct.getUnitPrice());
                stockInProduct.setUnitPrice(purchaseChangeOrderProduct.getUnitPrice());
                //成本价格
                if(purchaseChangeOrderProduct.getCostPrice()!=null){
                    stockInProduct.setCostPrice(purchaseChangeOrderProduct.getCostPrice());
                }
                //主材料单价
                if(purchaseChangeOrderProduct.getMainUnitPrice()!=null){
                    stockInProduct.setMainUnitPrice(purchaseChangeOrderProduct.getMainUnitPrice());
                }
                //主材料克重
                if(purchaseChangeOrderProduct.getGramWeight()!=null){
                    stockInProduct.setGramWeight(purchaseChangeOrderProduct.getGramWeight());
                }
                //工费
                if(purchaseChangeOrderProduct.getLaborCosts()!=null){
                    stockInProduct.setLaborCosts(purchaseChangeOrderProduct.getLaborCosts());
                }
                //修改损耗materialloss
                if(purchaseChangeOrderProduct.getMaterialloss()!=null){
                    stockInProduct.setMaterialloss(purchaseChangeOrderProduct.getMaterialloss());
                }
                //修改包装
                if(purchaseChangeOrderProduct.getMaterialpack()!=null){
                    stockInProduct.setMaterialpack(purchaseChangeOrderProduct.getMaterialpack());
                }
                //修改erp价格
                if(purchaseChangeOrderProduct.getErpprice()!=null){
                    stockInProduct.setErpprice(purchaseChangeOrderProduct.getErpprice());
                }
                //辅料
                if(purchaseChangeOrderProduct.getAccessoriesPrice()!=null){
                    stockInProduct.setAccessoriesPrice(purchaseChangeOrderProduct.getAccessoriesPrice());
                    //入库数量
                    if(stockInProduct.getUnitStock()!=null){
                        stockInProduct.setAccessoriesPriceAmount(purchaseChangeOrderProduct.getAccessoriesPrice().multiply(new BigDecimal(stockInProduct.getUnitStock())));
                    }
                }
                if(purchaseChangeOrderProduct.getUnitPrice()!=null){
                    stockInProduct.setArcd(purchaseChangeOrderProduct.getUnitPrice().multiply(new BigDecimal(stockInProduct.getQuantity())));
                }
                stockInProductService.updateById(stockInProduct);
            }
        }
    }

    /**
     * 更新采购订单
     * @param purchaseChangeOrder 变更单信息
     * @param purchaseOrder 采购单信息
     * @param list 变更单子表信息
     * @throws Exception
     */
    private void updatePurchaseOrder(PurchaseChangeOrderVo purchaseChangeOrder, PurchaseOrder purchaseOrder, List<PurchaseChangeOrderProduct> list) throws Exception {
        PurchaseOrderVo model=new PurchaseOrderVo();
        model.setId(purchaseOrder.getId());
        model.setOptUid(purchaseChangeOrder.getOptUid());
        model.setWid(purchaseChangeOrder.getWid());
        model.setPurchaser(purchaseChangeOrder.getPurchaser());
        model.setOtherCurrency(purchaseChangeOrder.getOtherFee());
        model.setSupplierId(purchaseChangeOrder.getSupplierId());
        model.setContactPerson(purchaseChangeOrder.getContactPerson());
        model.setContactNumber(purchaseChangeOrder.getContactNumber());
        model.setSettlementMethod(purchaseChangeOrder.getSettlementMethod());
        //advanceRatio
        model.setAdvanceRatio(purchaseChangeOrder.getAdvanceRatio());
        model.setSettlementDescribe(purchaseChangeOrder.getSettlementDescribe());
        //支付方式
        model.setPaymentMethod(purchaseChangeOrder.getPaymentMethod());
        model.setShippingPrice(purchaseChangeOrder.getShippingPrice());
        model.setOtherCurrency(purchaseChangeOrder.getOtherFee());
        model.setFeePartType(purchaseChangeOrder.getFeePartType());
        model.setIncludingTax(purchaseChangeOrder.getIncludingTax());
        model.setInspectionType(purchaseChangeOrder.getInspectionType());
        model.setRemarks(purchaseChangeOrder.getRemarks());
        //设置子表
        List<PurchaseOrderProductItemVo> PurchaseOrderProductItemVos=new ArrayList<>();
        for(int i=0;i<list.size();i++){
            PurchaseChangeOrderProduct purchaseChangeOrderProduct = list.get(i);
            PurchaseOrderProductItemVo purchaseOrderProductItemVo=new PurchaseOrderProductItemVo();
            if(purchaseChangeOrderProduct.getPurchaseOrderProductId()!=null){
                PurchaseOrderProduct byId = purchaseOrderProductService.getById(purchaseChangeOrderProduct.getPurchaseOrderProductId());
                BeanUtil.copyProperties(byId,purchaseOrderProductItemVo);
                if(byId.getQuantityReceived()!=null){
                    Assert.isTrue(purchaseChangeOrderProduct.getApplicationNum()>=byId.getQuantityReceived(),"采购数量不能小于到货数量");
                }

                //设置原数量大于修改后的数量
                if(purchaseChangeOrderProduct.getOriginalApplicationNum()>purchaseChangeOrderProduct.getApplicationNum()){
                    Integer cha=purchaseChangeOrderProduct.getOriginalApplicationNum().intValue()-purchaseChangeOrderProduct.getApplicationNum().intValue();
                   if(byId.getQuantityReceive()!=null){
                       purchaseOrderProductItemVo.setQuantityReceive(byId.getQuantityReceive()-cha);
                   }else{
                       purchaseOrderProductItemVo.setQuantityReceive(byId.getApplicationNum());

                   }
                    if(purchaseOrderProductItemVo.getBusinessIdent()==null){
                        purchaseOrderProductItemVo.setBusinessIdent("0");
                    }else{
                        if(!purchaseOrderProductItemVo.getBusinessIdent().contains("0")){
                            purchaseOrderProductItemVo.setBusinessIdent(purchaseOrderProductItemVo.getBusinessIdent()+",0");
                        }
                    }
                    purchaseChangeOrderProduct.setBusinessIdent("0");
                }else if(purchaseChangeOrderProduct.getOriginalApplicationNum()<purchaseChangeOrderProduct.getApplicationNum()){
                    Integer cha=purchaseChangeOrderProduct.getApplicationNum().intValue()-purchaseChangeOrderProduct.getOriginalApplicationNum().intValue();
                    if(byId.getQuantityReceive()!=null){
                        purchaseOrderProductItemVo.setQuantityReceive(byId.getQuantityReceive()+cha);
                    }else{
                        purchaseOrderProductItemVo.setQuantityReceive(purchaseChangeOrderProduct.getApplicationNum());
                    }
                    if(purchaseOrderProductItemVo.getBusinessIdent()==null){
                        purchaseOrderProductItemVo.setBusinessIdent("0");
                    }else{
                        if(!purchaseOrderProductItemVo.getBusinessIdent().contains("0")){
                            purchaseOrderProductItemVo.setBusinessIdent(purchaseOrderProductItemVo.getBusinessIdent()+",0");
                        }
                    }
                    purchaseChangeOrderProduct.setBusinessIdent("0");
                }
                if(purchaseChangeOrderProduct.getUnitPrice().compareTo(purchaseChangeOrderProduct.getOriginalUnitPrice())!=0){
                    if(purchaseOrderProductItemVo.getBusinessIdent()!=null&&!purchaseOrderProductItemVo.getBusinessIdent().contains("0")){
                        purchaseOrderProductItemVo.setBusinessIdent(purchaseOrderProductItemVo.getBusinessIdent()+",0");
                    }else if(purchaseOrderProductItemVo.getBusinessIdent()==null){
                        purchaseOrderProductItemVo.setBusinessIdent("0");
                    }
                    purchaseChangeOrderProduct.setBusinessIdent("0");
                }
                //成本价格
                if(purchaseChangeOrderProduct.getCostPrice()!=null){
                    purchaseOrderProductItemVo.setCostPrice(purchaseChangeOrderProduct.getCostPrice());
                }
                //主材料单价
                if(purchaseChangeOrderProduct.getMainUnitPrice()!=null){
                    purchaseOrderProductItemVo.setMainUnitPrice(purchaseChangeOrderProduct.getMainUnitPrice());
                }
                //主材料克重
                if(purchaseChangeOrderProduct.getGramWeight()!=null){
                    purchaseOrderProductItemVo.setGramWeight(purchaseChangeOrderProduct.getGramWeight());
                }
                //工费
                if(purchaseChangeOrderProduct.getLaborCosts()!=null){
                    purchaseOrderProductItemVo.setLaborCosts(purchaseChangeOrderProduct.getLaborCosts());
                }
                //辅料
                if(purchaseChangeOrderProduct.getAccessoriesPrice()!=null){
                    purchaseOrderProductItemVo.setAccessoriesPrice(purchaseChangeOrderProduct.getAccessoriesPrice());
                }
                //损耗
                if(purchaseChangeOrderProduct.getMaterialloss()!=null){
                    purchaseOrderProductItemVo.setMaterialloss(purchaseChangeOrderProduct.getMaterialloss());
                }
                //包装
                if(purchaseChangeOrderProduct.getMaterialpack()!=null){
                    purchaseOrderProductItemVo.setMaterialpack(purchaseChangeOrderProduct.getMaterialpack());
                }
                //erp单价
                if(purchaseChangeOrderProduct.getErpprice()!=null){
                    purchaseOrderProductItemVo.setErpprice(purchaseChangeOrderProduct.getErpprice());
                }

                purchaseOrderProductItemVo.setId(purchaseChangeOrderProduct.getPurchaseOrderProductId().longValue());
                purchaseOrderProductItemVo.setPurchaseOrderId(byId.getPurchaseOrderId());
            }
            //新增的产品
            else{
                purchaseOrderProductItemVo.setProductId(purchaseChangeOrderProduct.getProductId());
                purchaseOrderProductItemVo.setSid(purchaseChangeOrderProduct.getSid());
                purchaseOrderProductItemVo.setSku(purchaseChangeOrderProduct.getSku());
                if(purchaseChangeOrderProduct.getFnsku()!=null){
                    purchaseOrderProductItemVo.setFnsku(Long.valueOf(purchaseChangeOrderProduct.getFnsku()));
                    ListingFatherVo voById = listingFatherService.getVoById(purchaseChangeOrderProduct.getFnsku());
                    purchaseOrderProductItemVo.setLxFnsku(voById.getFnsku());
                    purchaseOrderProductItemVo.setFnskuFnsku(voById.getFnsku());
                }
                //设置待到货数量
                purchaseOrderProductItemVo.setQuantityReceive(purchaseChangeOrderProduct.getApplicationNum());
                purchaseOrderProductItemVo.setBusinessIdent("0");
                purchaseChangeOrderProduct.setBusinessIdent("0");
            }
            purchaseChangeOrderProductService.updateById(purchaseChangeOrderProduct);
            purchaseOrderProductItemVo.setApplicationNum(purchaseChangeOrderProduct.getApplicationNum());
            purchaseOrderProductItemVo.setUnitPrice(purchaseChangeOrderProduct.getUnitPrice());
            //成本价格
            if(purchaseChangeOrderProduct.getCostPrice()!=null){
                purchaseOrderProductItemVo.setCostPrice(purchaseChangeOrderProduct.getCostPrice());
            }
            //主材料单价
            if(purchaseChangeOrderProduct.getMainUnitPrice()!=null){
                purchaseOrderProductItemVo.setMainUnitPrice(purchaseChangeOrderProduct.getMainUnitPrice());
            }
            //主材料克重
            if(purchaseChangeOrderProduct.getGramWeight()!=null){
                purchaseOrderProductItemVo.setGramWeight(purchaseChangeOrderProduct.getGramWeight());
            }
            //工费
            if(purchaseChangeOrderProduct.getLaborCosts()!=null){
                purchaseOrderProductItemVo.setLaborCosts(purchaseChangeOrderProduct.getLaborCosts());
            }
            //辅料
            if(purchaseChangeOrderProduct.getAccessoriesPrice()!=null){
                purchaseOrderProductItemVo.setAccessoriesPrice(purchaseChangeOrderProduct.getAccessoriesPrice());
            }
            //损耗
            if(purchaseChangeOrderProduct.getMaterialloss()!=null){
                purchaseOrderProductItemVo.setMaterialloss(purchaseChangeOrderProduct.getMaterialloss());
            }
            //包装
            if(purchaseChangeOrderProduct.getMaterialpack()!=null){
                purchaseOrderProductItemVo.setMaterialpack(purchaseChangeOrderProduct.getMaterialpack());
            }
            //erp单价
            if(purchaseChangeOrderProduct.getErpprice()!=null){
                purchaseOrderProductItemVo.setErpprice(purchaseChangeOrderProduct.getErpprice());
            }

            purchaseOrderProductItemVo.setTaxPrice(purchaseChangeOrderProduct.getTaxPrice());
            purchaseOrderProductItemVo.setTaxRate(purchaseChangeOrderProduct.getTaxRate());
            //taxAmount taxRate
            purchaseOrderProductItemVo.setTaxAmount(purchaseChangeOrderProduct.getTaxAmount());
            purchaseOrderProductItemVo.setTotalPrice(purchaseChangeOrderProduct.getTotalPrice());
//            purchaseOrderProductItemVo.setArrivalDate(purchaseChangeOrderProduct.getExpectArriveTime());
            purchaseOrderProductItemVo.setRemarks(purchaseChangeOrderProduct.getRemark());
            purchaseOrderProductItemVo.setExpectArriveTime(purchaseChangeOrderProduct.getExpectArriveTime());
            PurchaseOrderProductItemVos.add(purchaseOrderProductItemVo);

        }
        model.setPurchaseOrde(PurchaseOrderProductItemVos);
        model.setAnStatus(purchaseOrder.getAnStatus());
        model.setArrivalStatus(purchaseOrder.getArrivalStatus());//设置为待到货状态
        //把不在集合中的删除掉
        List<Long> ids=list.stream().filter(x->x.getPurchaseOrderProductId()!=null).map(x->Long.valueOf(x.getPurchaseOrderProductId())).collect(Collectors.toList());
        List<Long> ids2=purchaseOrderProductService.list(Wrappers.<PurchaseOrderProduct>query().lambda().eq(PurchaseOrderProduct::getPurchaseOrderId,purchaseOrder.getId())).stream().map(PurchaseOrderProduct::getId).collect(Collectors.toList());
        boolean b = ids2.removeAll(ids);
        if(b){
            purchaseOrderProductService.removeBatchByIds(ids2);
        }else{
            Assert.isTrue(false,"执行异常!");
        }
        purchaseOrderService.update(model);
    }

    /**
     * 更新请款池金额
     * @param purchaseChangeOrder
     * @throws Exception
     */
    public void updateFundsPayPool(PurchaseChangeOrderVo purchaseChangeOrder) throws Exception {
        final String settlementMethod = purchaseChangeOrder.getSettlementMethod();
        final List<PurchaseChangeOrderProductItemVo> productItem = purchaseChangeOrder.getProductItem();

        if(settlementMethod.equals("JS01")){ //现结
//            LoanNowBalanceVo loanNowBalanceVo = loanNowBalanceService.getVoById(loanNowBalanceService.getIdByPurchaseOrderCode(purchaseChangeOrder.getOrderSn()));
            LoanNowBalance loanNowBalance = loanNowBalanceService.getOne(Wrappers.lambdaQuery(LoanNowBalance.class)
                    .eq(LoanNowBalance::getPurchaseOrderCode,purchaseChangeOrder.getOrderSn()));
            if(null == loanNowBalance){
                return;
            }
            loanNowBalance.setPurchaseQuantity(productItem.stream().mapToInt(p -> p.getApplicationNum()).sum());
            BigDecimal purchaseMoney = productItem.stream().map(p -> p.getTotalPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
            loanNowBalance.setAmountPayable(loanNowBalance.getAmountPayable().add(purchaseMoney.subtract(loanNowBalance.getPurchaseMoney())));
            loanNowBalance.setNotApply(loanNowBalance.getNotApply().add(purchaseMoney.subtract(loanNowBalance.getPurchaseMoney())));
            loanNowBalance.setGoodsPrice(purchaseMoney);
            loanNowBalance.setPurchaseMoney(purchaseMoney);
            if(loanNowBalance.getStatus().equals("40")){
                loanNowBalance.setStatus("30");
            }
            loanNowBalanceService.updateById(loanNowBalance);
        }else if(settlementMethod.equals("JS02")){ //月结
//            LoanMonthlyBalanceVo loanMonthlyBalanceVo = loanMonthlyBalanceService.getVoById(loanMonthlyBalanceService.getIdByPurchaseOrderCode(purchaseChangeOrder.getOrderSn()));
            LoanMonthlyBalance loanMonthlyBalance = loanMonthlyBalanceService.getOne(Wrappers.lambdaQuery(LoanMonthlyBalance.class)
                    .eq(LoanMonthlyBalance::getPurchaseOrderCode,purchaseChangeOrder.getOrderSn()));
            if(null == loanMonthlyBalance){
                return;
            }
//            LoanMonthlyBalanceProductItemVo loanMonthlyBalanceProductItemVo = loanMonthlyBalanceVo.getLists().get(0);
            BigDecimal purchaseMoney = productItem.stream().map(p -> p.getTotalPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
            loanMonthlyBalance.setPurchaseQuantity(productItem.stream().mapToInt(p -> p.getApplicationNum()).sum());
//            loanMonthlyBalance.setQkMoney(loanMonthlyBalance.getQkMoney().add(purchaseMoney.subtract(loanMonthlyBalance.getPurchaseMoney())));
            loanMonthlyBalance.setNotApply(loanMonthlyBalance.getNotApply().add(purchaseMoney.subtract(loanMonthlyBalance.getPurchaseMoney())));
            loanMonthlyBalance.setGoodsPrice(purchaseMoney);
            loanMonthlyBalance.setPurchaseMoney(purchaseMoney);
            if(loanMonthlyBalance.getStatus().equals("40")){
                loanMonthlyBalance.setStatus("30");
            }
            loanMonthlyBalanceService.updateById(loanMonthlyBalance);
        }else {
            Assert.isTrue(false,"结算方式错误!");
        }
    }

}
